#include <iostream>
#include <thread>

#include "thread_guard.h"

/**
 * @brief 仿函数
 */
class background_thread
{
public:
    /**
     * @brief 可调用对象
     */
    void operator() () const
    {
        std::cout << "Background thread is running." << std::endl;
    }
};

int main()
{
    std::string strLocalVar{"Local variable in main."}; // 定义一个局部变量

    background_thread f{};
    std::thread t{f}; // 创建一个线程，执行仿函数 f
    std::thread t1{background_thread{}}; // 直接传递仿函数的临时对象
    t.join(); // 等待线程 t 完成
    t1.join(); // 等待线程 t1 完成

    std::thread t2{[&strLocalVar]()
    {
        // 以引用的形式捕获局部变量
        std::cout << "Background thread is running." << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟一些工作

        for (int i = 0; i < 10; ++i)
        {
            std::cout << strLocalVar << std::endl; // 打印局部变量
        }
    }}; // 使用 lambda 表达式创建线程
    t2.detach(); // 分离线程 t2，使其在后台运行
    // t2.join();

    std::thread t3{background_thread{}};
    ThreadGuard guard{t3}; // 移交线程管理给 ThreadGuard

    // 向线程函数传递参数
    auto func = [](int nCount , const std::string& str)
    {
        for (int i = 0; i < nCount; ++i)
        {
            std::cout << str << std::endl;
        }
    };

    // 线程的构造函数会自动将参数补齐
    std::thread t4{func , 10 , "Hello from thread!"}; // 创建线程并传递参数,这里传进去的是const char* 进入线程的上下文环境才转化为std::string
    t4.join(); // 等待线程 t4 完成
    const std::string& cstr{"Hello from thread with const ref!"};
    std::thread t5{func , 10 , std::cref(cstr)}; // 使用 std::cref 传递常量引用
    t5.join();

    {
        char buffer[1024]{}; // 局部字符数组
        // std::thread t6{func , 10 , buffer}; // 传递局部字符数组
        std::thread t6{func,10, std::string(buffer)}; // 将字符数组转换为 std::string
        t.detach();
        //
    }

    auto func2 = []()
    {
        auto id = std::this_thread::get_id(); // 获取当前线程的 ID
        std::cout << id << std::endl;
    };
    std::thread t7{func2};
    auto id = t7.get_id();
    t7.join();
    id = std::this_thread::get_id(); // 获取主线程的 ID

    return 0;
}